﻿using System;
using System.Collections.Generic;
using SubSonic.Query;

/***********************************
 * 
 * 条件类
 * 修改说明：保留原有的设计思想，将原条件类修改为适应SubSonic3.0插件调用
 * 
 ***********************************/

namespace DataAccess.DbHelper
{
    /// <summary>
    /// 条件类
    /// </summary>
	public class ConditionHelper
    {
		/// <summary>SqlQuery条件类
		/// </summary>
		public class SqlqueryCondition {
			/// <summary>
			/// SqlQuery条件类构造函数
			/// </summary>
			/// <param name="ctype">查询类型，包括：Where、And、Or</param>
			/// <param name="columnname">条件列名</param>
			/// <param name="cparsion">条件表达式类型</param>
			/// <param name="value">条件值</param>
			/// <param name="isParentheses">是否加左括号</param>
            public SqlqueryCondition(ConstraintType ctype, string columnname, Comparison cparsion, object value) {
                SQConstraintType = ctype;
                SQColumnName = columnname;
                SQComparison = cparsion;
                SQValue = value;
                IsParentheses = false;
                IsOr = false;
            }
			public SqlqueryCondition(ConstraintType ctype, string columnname, Comparison cparsion, object value, bool isParentheses, bool isOr) {
				SQConstraintType = ctype;
				SQColumnName = columnname;
				SQComparison = cparsion;
				SQValue = value;
				IsParentheses = isParentheses;
				IsOr = isOr;
			}
			/// <summary>
			/// 添加右括号
			/// </summary>
			/// <param name="cparsion"></param>
			public SqlqueryCondition() {
                SQComparison = Comparison.CloseParentheses;
                IsParentheses = true;
            }
            public SqlqueryCondition(Comparison cparsion) {
				SQComparison = cparsion;
				IsParentheses = true;
			}

			private ConstraintType _sqConstraintType;
			/// <summary>
			/// 查询类型，包括：Where、And、Or
			/// </summary>
			public ConstraintType SQConstraintType {
				get { return _sqConstraintType; }
				set { _sqConstraintType = value; }
			}

			private String _sqColumnName;
			/// <summary>
			/// 条件列名
			/// </summary>
			public String SQColumnName {
				get { return _sqColumnName; }
				set { _sqColumnName = value; }
			}

			private Comparison _sqComparison;
			/// <summary>
			/// 条件表达式类型
			/// </summary>
			public Comparison SQComparison {
				get { return _sqComparison; }
				set { _sqComparison = value; }
			}

			private object _sqValue;
			/// <summary>
			/// 条件值
			/// </summary>
			public object SQValue {
				get { return _sqValue; }
				set { _sqValue = value; }
			}

			private bool _isParentheses = false;
			/// <summary>
			/// 加括号
			/// </summary>
			public bool IsParentheses {
				get { return _isParentheses; }
				set { _isParentheses = value; }
			}

			private bool _isOr = false;
			/// <summary>
			/// 是否使用Or查询条件，主要用于使用In查询时，
			/// 由于In的内容之间是保持Or关系，
			/// 所以默认状态与前一个条件是And关系，
			/// 如果想要与前一个条件保持Or查询关系，则需要将IsOr设为true
			/// </summary>
			public bool IsOr {
				get { return _isOr; }
				set { _isOr = value; }
			}

			private bool _isBrackets = true;

			public bool IsBrackets {
				get { return _isBrackets; }
				set { _isBrackets = value; }
			}

			/// <summary>为SqlQuery添加条件
			/// </summary>
			/// <param name="sqlquery">SqlQuery查询对象</param>
			/// <param name="scd">SqlQuery条件实体</param>
			public static void AddSqlqueryCondition(SqlQuery sqlquery, List<SqlqueryCondition> scd) {
				if (scd == null)
					return;

				foreach (SqlqueryCondition item in scd) {
					//如果查询条件不为空
					if (item != null) {
						item.IsBrackets = true;

						switch (item.SQComparison) {
							case Comparison.Equals:
								AddConstraint(sqlquery, item).IsEqualTo(item.SQValue);
								break;
							case Comparison.NotEquals:
								AddConstraint(sqlquery, item).IsNotEqualTo(item.SQValue);
								break;
							case Comparison.Like:
								AddConstraint(sqlquery, item).Like(item.SQValue.ToString());
								break;
							case Comparison.NotLike:
								AddConstraint(sqlquery, item).NotLike(item.SQValue.ToString());
								break;
							case Comparison.GreaterThan:
								AddConstraint(sqlquery, item).IsGreaterThan(item.SQValue);
								break;
							case Comparison.GreaterOrEquals:
								AddConstraint(sqlquery, item).IsGreaterThanOrEqualTo(item.SQValue);
								break;
							case Comparison.LessThan:
								AddConstraint(sqlquery, item).IsLessThan(item.SQValue);
								break;
							case Comparison.LessOrEquals:
								AddConstraint(sqlquery, item).IsLessThanOrEqualTo(item.SQValue);
								break;
							case Comparison.Is:
								AddConstraint(sqlquery, item).IsNull();
								break;
							case Comparison.IsNot:
								AddConstraint(sqlquery, item).IsNotNull();
								break;
							case Comparison.In:
								/**
								 * 由于底层插件使用In查询时，查询条件值在最终转换时老是出错，所以就将它转换成单个值拼起来的条件
								 * For Empty 2013-09-12 
								 */
								if (item.SQValue != null) {
									try {
										var obj = (object[])item.SQValue;
										for (int i = 0; i < obj.Length; i++) {
											if (i == 0)
												AddConstraint(sqlquery, item, true).IsEqualTo(obj[i]);
											else {
												//In查询时，第二个参数开始就不能再继续加括号了，所以设置为false
												item.IsBrackets = false;
												AddConstraint(sqlquery, item).IsEqualTo(obj[i]);
											}
										}
									}
									catch (Exception) {
										AddConstraint(sqlquery, item).In(item.SQValue);
									}
								}

								break;
							case Comparison.NotIn:
								AddConstraint(sqlquery, item).NotIn(item.SQValue);
								break;
							case Comparison.OpenParentheses:
								AddConstraint(sqlquery, item).In(item.SQValue);
								break;
							case Comparison.CloseParentheses:
								sqlquery.CloseExpression();
								break;
							//case Comparison.BetweenAnd:
							//    AddConstraint(sqlquery, item).IsBetweenAnd(item.SQValue, item.SQValue2);
							//    break;
							case Comparison.StartsWith:
								AddConstraint(sqlquery, item).StartsWith(item.SQValue.ToString());
								break;
							case Comparison.EndsWith:
								AddConstraint(sqlquery, item).EndsWith(item.SQValue.ToString());
								break;
						}
					}
				}
			}

			/// <summary>
			/// 添加查询条件，如果存在括号时，则自动判断加上括号
			/// </summary>
			/// <param name="sqlquery">SqlQuery查询对象</param>
			/// <param name="item">当前SqlQuery条件实体</param>
			/// <param name="isIn">是否是In查询，是的话第一次加And</param>
			/// <returns></returns>
			public static Constraint AddConstraint(SqlQuery sqlquery, SqlqueryCondition item) {
                return AddConstraint(sqlquery, item, false);
            }
            public static Constraint AddConstraint(SqlQuery sqlquery, SqlqueryCondition item, bool isIn) {
				//判断是Where查询还是And查询
				if (ConstraintType.Where.Equals(item.SQConstraintType) ||
					ConstraintType.And.Equals(item.SQConstraintType) || (isIn && !item.IsOr)) {
					//判断是否需要加括号
					if (item.IsParentheses && item.IsBrackets) {
						return sqlquery.AndExpression(item.SQColumnName);
					}
					else
						return sqlquery.And(item.SQColumnName);
				}
				//使用Or查询
				else {
					//判断是否需要加括号
					if (item.IsParentheses && item.IsBrackets) {
						return sqlquery.OrExpression(item.SQColumnName);
					}
					else
						return sqlquery.Or(item.SQColumnName);
				}
			}


			/// <summary>
			/// 生成SqlQuery类调用时所需要的条件格式——目前查询条件中不能使用括号，如果需要须修改代码
			/// </summary>
			/// <param name="scd">SqlQuery条件类</param>
			public static List<Constraint> Condition(List<SqlqueryCondition> scd) {
				if (scd == null)
					return null;

				var constrain = new List<Constraint>();

				foreach (SqlqueryCondition item in scd) {
					if (item != null) {
						var con = new Constraint(item.SQConstraintType, item.SQColumnName);
						con.Comparison = item.SQComparison;
						con.ParameterValue = item.SQValue;
						constrain.Add(con);
					}
				}

				return constrain;
			}
		}
    }
}
